﻿using Anotar.LibLog;
using Autofac;
using Autofac.Extras.Quartz;
using Autofac.Integration.Web;
using Microsoft.Owin;
using Newbe.TestDirector.Notification.Web;
using Newbe.TestDirector.Notification.Web.Domain;
using Newbe.TestDirector.Notification.Web.Entities;
using Newbe.TestDirector.Notification.Web.Jobs;
using Owin;
using Quartz;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;

[assembly: OwinStartup(typeof(Startup))]

namespace Newbe.TestDirector.Notification.Web
{
    public class Startup
    {
        [LogToFatalOnException]
        public void Configuration(IAppBuilder app)
        {
            LogTo.Info("Application Startting...");
            var container = InitContainer();
            Global.StaticContainerProvider = new ContainerProvider(container);
            using (var efContext = container.Resolve<IEfContext>())
            {
                efContext.Init();
            }
            var scheduler = container.Resolve<IScheduler>();
            var jobs = container.Resolve<IEnumerable<IMyJob>>();
            foreach (var job in jobs)
            {
                var triggerBuilder = TriggerBuilder.Create();
                ITrigger trigger;
                if (string.IsNullOrEmpty(job.CronExpression))
                {
                    trigger = triggerBuilder.StartNow()
                        .WithCalendarIntervalSchedule(c => c.WithIntervalInSeconds((int)job.ActTime.TotalSeconds))
                        .Build();
                }
                else
                {
                    trigger = triggerBuilder.StartNow()
                        .WithCronSchedule(job.CronExpression)
                        .Build();
                }
                var jobDetail = JobBuilder.Create(job.GetType()).Build();
                scheduler.ScheduleJob(jobDetail, trigger);
            }
            scheduler.Start();
            LogTo.Info("Appplication Started.");
        }

        private static IContainer InitContainer()
        {
            var cb = new ContainerBuilder();
            cb.RegisterModule<AutofacModule>();
            // 1) Register IScheduler
            cb.RegisterModule(new QuartzAutofacFactoryModule());
            // 2) Register jobs
            cb.RegisterModule(new QuartzAutofacJobsModule(typeof(Startup).Assembly));
            var systemOptions = InitSystemOptions();
            cb.RegisterInstance(systemOptions).SingleInstance();

            var container = cb.Build();
            return container;
        }

        private static SystemOptions InitSystemOptions()
        {
            var options = new SystemOptions
            {
                TestDirectorDatabaseFilePath = GetAppSetting<string>("TestDirectorDatabaseFilePath"),
                MailJobCronExpression = GetAppSetting("MailJobCronExpression", "0 15 10 * * ?"),
                MailBodyTemplateFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Views/MailBodyTemplate.cshtml"),
                MailerOptions = new MailerOptions
                {
                    FromAddress = GetAppSetting<string>("SenderUsername"),
                    SenderUsername = GetAppSetting<string>("SenderUsername"),
                    SenderPassord = GetAppSetting<string>("SenderPassord"),
                }
            };
            return options;
        }

        private static T GetAppSetting<T>(string name)
        {
            var value = ConfigurationManager.AppSettings[name];
            if (string.IsNullOrEmpty(value))
            {
                throw new MissingAppSettingException(name);
            }
            return (T)Convert.ChangeType(value, typeof(T));
        }

        private static T GetAppSetting<T>(string name, T defaultValue)
        {
            var value = ConfigurationManager.AppSettings[name];
            if (string.IsNullOrEmpty(value))
            {
                return defaultValue;
            }
            return (T)Convert.ChangeType(value, typeof(T));
        }
    }
}
